home *** CD-ROM | disk | FTP | other *** search
/ Amiga Collections: Various / DevDisk 65 (1989)(DevWare PD).zip / DevDisk 65 (1989)(DevWare PD).adf / prosuite / filesupp.c < prev    next >
C/C++ Source or Header  |  1990-07-11  |  19KB  |  711 lines

  1.  
  2. /* *** filesupp.c ***********************************************************
  3.  *
  4.  * File IO Suite  --  Open Requester Routines
  5.  *     from Book 1 of the Amiga Programmers' Suite by RJ Mical
  6.  *
  7.  * Copyright (C) 1986, 1987, Robert J. Mical
  8.  * All Rights Reserved.
  9.  *
  10.  * Created for Amiga developers.
  11.  * Any or all of this code can be used in any program as long as this
  12.  * entire copyright notice is retained, ok?  Thanks.
  13.  *
  14.  * The Amiga Programmer's Suite Book 1 is copyrighted but freely distributable.
  15.  * All copyright notices and all file headers must be retained intact.
  16.  * The Amiga Programmer's Suite Book 1 may be compiled and assembled, and the 
  17.  * resultant object code may be included in any software product.  However, no 
  18.  * portion of the source listings or documentation of the Amiga Programmer's 
  19.  * Suite Book 1 may be distributed or sold for profit or in a for-profit 
  20.  * product without the written authorization of the author, RJ Mical.
  21.  * 
  22.  * HISTORY      NAME            DESCRIPTION
  23.  * -----------  --------------  --------------------------------------------
  24.  * 20 Oct 87    - RJ            Added RENAME_RAMDISK to fix what seems to 
  25.  *                              be a bug in either AmigaDOS or Workbench.
  26.  * 27 Sep 87    RJ              In order to show the correct DiskName during
  27.  *                              WarmStartFileIO(), that routine now 
  28.  *                              refreshes the gadgets both before and after 
  29.  *                              the BuildNameTable() process.
  30.  * 4 Feb 87     RJ              Real release
  31.  * 12 Aug 86    RJ >:-{)*       Prepare (clean house) for release
  32.  * 3 May 86     =RJ Mical=      Fix prop gadget for both 1.1 and 1.2
  33.  * 1 Feb 86     =RJ Mical=      Created this file.
  34.  *
  35.  * *********************************************************************** */
  36.  
  37.  
  38. #define FILEIO_SOURCEFILE
  39. #include "fileio.h"
  40.  
  41.  
  42. /* I think these are silly, but I put them here anyway to avoid compiler
  43.  * warnings.
  44.  */
  45. VOID InitOpenProp();
  46. VOID StuffSelectNames();
  47.  
  48.  
  49.  
  50. /* ======================================================================= */
  51. /* === ResetText Routines ================================================ */
  52. /* ======================================================================= */
  53.  
  54. VOID ResetTextGrunt(info, resetbuffer)
  55. struct StringInfo *info;
  56. BOOL resetbuffer;
  57. /* Reset the string position variables, and reset the buffer itself if
  58.  * resetbuffer is TRUE.
  59.  */
  60. {
  61.     info->BufferPos = info->DispPos = 0;
  62.     if (resetbuffer) info->Buffer[0] = '\0';
  63. }
  64.  
  65. VOID ResetNameText(resetbuffer)
  66. BOOL resetbuffer;
  67. {
  68.     ResetTextGrunt(&OpenNameTextInfo, resetbuffer);
  69. }
  70.  
  71. VOID ResetDrawerText(resetbuffer)
  72. BOOL resetbuffer;
  73. {
  74.     ResetTextGrunt(&OpenDrawerTextInfo, resetbuffer);
  75. }
  76.  
  77. VOID ResetDiskText(resetbuffer)
  78. BOOL resetbuffer;
  79. {
  80.     ResetTextGrunt(&OpenDiskTextInfo, resetbuffer);
  81. }
  82.  
  83.  
  84.  
  85. /* ======================================================================= */
  86. /* === WarmStart Initializer ============================================= */
  87. /* ======================================================================= */
  88.  
  89. VOID WarmStartFileIO(fileio)
  90. struct FileIOSupport *fileio;
  91. /* This routine establishes a lock on the current disk and drawer,
  92.  * resets all of the subsystem control variables,
  93.  * gets the file names for the current disk and drawer,
  94.  * initializes the proportional gadget,
  95.  * and then refreshes the requester.
  96.  */
  97. {
  98.     ULONG lock;
  99.  
  100.     /* If the fileio already had a lock, release it before proceeding */
  101.     if (FlagIsSet(fileio->Flags, LOCK_GOTTEN))
  102.         {
  103.         UnLock(fileio->DOSLock);
  104.         ClearFlag(fileio->Flags, LOCK_GOTTEN);
  105.         fileio->DOSLock = OpenSaveLock;
  106.         CurrentDir(OpenSaveLock);
  107.         }
  108.  
  109.     /* Build the lock name using the current disk and drawer names */
  110.     if (StringLength(&fileio->DiskName[0]))
  111.         CopyString(&OpenLockName[0], &fileio->DiskName[0]);
  112.     else
  113.         CopyString(&OpenLockName[0], CurrentVolumeName());
  114.  
  115.     /* If the programmer wants us to sidestep the "RAM DISK:" bug, 
  116.      * then by all means oblige her or him.
  117.      */
  118.     if (FlagIsSet(fileio->Flags, RENAME_RAMDISK) 
  119.             && CompareUpperStrings(&OpenLockName[0], 
  120.             "RAM DISK:") == 0)
  121.         {
  122.         /* Everyone seems suspicious of "RAM Disk:" */
  123.         OpenLockName[3] = ':';
  124.         OpenLockName[4] = '\0';
  125.         }
  126.  
  127.     ConcatString(&OpenLockName[0], &fileio->DrawerName[0]);
  128.  
  129.     /* Can we get a lock on this name? */
  130.     if (lock = Lock(&OpenLockName[0], ACCESS_READ))
  131.         {
  132.         /* Got it! */
  133.         SetFlag(fileio->Flags, LOCK_GOTTEN);
  134.         fileio->DOSLock = lock;
  135.         CurrentDir(lock);
  136.         }
  137.     else
  138.         {
  139.         /* Hey, bad break, this name just won't do.  But the rest of these
  140.          * routines need a valid directory, so go back home.
  141.          */
  142.         Alert(ALERT_BAD_DIRECTORY, OpenReqWindow);
  143.         CopyString(&fileio->DiskName[0], &CurrentDiskString[0]);
  144.         ResetDiskText(FALSE);
  145.         ResetDrawerText(TRUE);
  146.         }
  147.  
  148.     /* Reset the fileio name selection variables */
  149.     fileio->CurrentPick = -1;
  150.     fileio->NameStart = 0;
  151.     fileio->NameCount = 0;
  152.  
  153.     /* Reset the text and gadgets */
  154.     InitOpenProp(TRUE);                /* Initialize the prop gadget */
  155.     StuffSelectNames(-1);            /* Display all of the names */
  156.     BuildNameTable(OpenReqFileIO);    /* Get the file names */
  157.     StuffSelectNames(1);            /* Display the file names */
  158. }
  159.  
  160.  
  161.  
  162. /* ======================================================================= */
  163. /* === Select Name Routines ============================================== */
  164. /* ======================================================================= */
  165.  
  166. VOID BlankSelectText(index)
  167. SHORT index;
  168. /* This routine truns the SelectText at index into blanks */
  169. {
  170.     UBYTE *ptr;
  171.     SHORT blanklength;
  172.  
  173.     ptr = &OpenSelectBuffers[index][0];
  174.     for (blanklength = VISIBLE_SELECT_LENGTH - 1; blanklength; blanklength--)
  175.         *ptr++ = ' ';
  176.     *ptr = '\0';
  177.  
  178.     OpenSelectText[index].FrontPen = 1;
  179.     OpenSelectText[index].BackPen = 0;
  180. }
  181.  
  182.  
  183.  
  184. VOID DrawSelectNames()
  185. {
  186.     struct Layer *layer;
  187.  
  188.     Forbid();
  189.     if (layer = OpenReq->ReqLayer)
  190.         if (layer->rp)
  191.             PrintIText(layer->rp,
  192.                     &OpenSelectText[NAME_ENTRY_COUNT - 1], 
  193.                     OPENSELECT_LEFT, OPENSELECT_TOP);
  194.     Permit();
  195. }
  196.  
  197.  
  198.  
  199. VOID StuffSelectNames(refreshcount)
  200. SHORT refreshcount;
  201. /* This routine stuffs the Open Requester's filename gadgets with
  202.  * names from the fileio structure, starting from the 
  203.  * fileio->NameStart name.  If the refreshcount is nonzero, the gadgets
  204.  * will be refreshed too.
  205.  */
  206. {
  207.     SHORT i, end, bufferpos;
  208.     SHORT length, blanklength;
  209.     UBYTE *ptr, *ptr2;
  210.     struct Remember *remember;
  211.     struct Layer *layer;
  212.  
  213.     if (OpenReqFileIO->NameCount 
  214.             > OpenReqFileIO->NameStart + NAME_ENTRY_COUNT) 
  215.         end = OpenReqFileIO->NameStart + NAME_ENTRY_COUNT;
  216.     else end = OpenReqFileIO->NameCount;
  217.  
  218.     bufferpos = 0;
  219.  
  220.     /* The current file names are stored in the fileio's Remember list */
  221.     remember = OpenReqFileIO->NameKey;
  222.     for (i = 0; i < OpenReqFileIO->NameStart; i++) 
  223.         remember = remember->NextRemember;
  224.  
  225.     for (i = OpenReqFileIO->NameStart; i < end; i++) 
  226.         {
  227.         ptr = &OpenSelectBuffers[bufferpos][0];
  228.         ptr2 = remember->Memory;
  229.  
  230.         length = StringLength(ptr2);
  231.         if (length >= VISIBLE_SELECT_LENGTH)
  232.             length = VISIBLE_SELECT_LENGTH - 1;
  233.         blanklength = (VISIBLE_SELECT_LENGTH - 1) - length;
  234.  
  235.         /* By filling up the IntuiText with blanks after the characters,
  236.          * the text, when printed, will overstrike any characters that were 
  237.          * there before.
  238.          */
  239.         for ( ; length; length--) *ptr++ = *ptr2++;
  240.         for ( ; blanklength; blanklength--) *ptr++ = ' ';
  241.         *ptr = '\0';
  242.  
  243.         /* If this is the selected text, then use "highlight" pens */
  244.         if (i == OpenReqFileIO->CurrentPick)
  245.             {
  246.             OpenSelectText[bufferpos].FrontPen = -2;
  247.             OpenSelectText[bufferpos].BackPen = -1;
  248.             }
  249.         else
  250.             {
  251.             OpenSelectText[bufferpos].FrontPen = 1;
  252.             OpenSelectText[bufferpos].BackPen = 0;
  253.             }
  254.  
  255.         bufferpos++;
  256.         remember = remember->NextRemember;
  257.         }
  258.  
  259.     /* Now, for all lines that have no entries, fill with blanks */
  260.     for ( ; bufferpos < NAME_ENTRY_COUNT; bufferpos++)
  261.         BlankSelectText(bufferpos);
  262.  
  263.     /* Finally, redraw the lot */
  264.     if (refreshcount)
  265.         {
  266.         Forbid();
  267.         if (layer = OpenReq->ReqLayer)
  268.             if (layer->rp)
  269.                 RefreshGList(&OpenSelectNameGadget, OpenReqWindow, OpenReq,
  270.                         refreshcount);
  271.         DrawSelectNames();
  272.         Permit();
  273.         }
  274. }
  275.  
  276.  
  277.  
  278. VOID SetNameStart()
  279. /* This little guy sets the NameStart based on the current
  280.  * prop gadget setting.
  281.  */
  282. {
  283.     if (OpenReqFileIO->NameCount <= NAME_ENTRY_COUNT)
  284.         OpenReqFileIO->NameStart = 0;
  285.     else
  286.         OpenReqFileIO->NameStart = (OpenPropInfo.VertPot 
  287.                 * (OpenReqFileIO->NameCount - NAME_ENTRY_COUNT + 1)) >> 16;
  288. }
  289.  
  290.  
  291.  
  292. VOID StripLastDrawer()
  293. /* This guy strips the end drawer reference off of the drawer string,
  294.  * which includes nulling out the string if there's only one to strip.
  295.  */
  296. {
  297.     UBYTE *ptr;
  298.     SHORT index;
  299.  
  300.     ptr = OpenDrawerTextInfo.Buffer;
  301.     index = IndexString(ptr, "/");
  302.     if (index != -1)
  303.         {
  304.         /* OK, there's more than one drawer reference, so get the ptr + index
  305.          * to the last one.
  306.          */
  307.         do 
  308.             ptr += (index + 1);
  309.         while ((index = IndexString(ptr, "/")) != -1);
  310.         }
  311.     else index = 0;
  312.     /* Zammo! */
  313.     *(ptr + index) = '\0';
  314. }
  315.  
  316.  
  317.  
  318. BOOL DirectoryName()
  319. /* Returns TRUE if the selected name was a directory-type reference
  320.  * (up or down), else returns FALSE for a normal filename.
  321.  */
  322. {
  323.     struct Remember *nextentry;
  324.     SHORT i;
  325.     UBYTE entryflags;
  326.  
  327.     if (OpenReqFileIO->NameCount)
  328.         {
  329.         /* Find the selected entry in the key list */
  330.         nextentry = OpenReqFileIO->NameKey;
  331.         for (i = OpenReqFileIO->CurrentPick; i > 0; i--)
  332.             nextentry = nextentry->NextRemember;
  333.         i = StringLength(nextentry->Memory) + 1;
  334.         entryflags = *(nextentry->Memory + i);
  335.  
  336.         if (FlagIsSet(entryflags, NAMED_DIRECTORY | NAMED_PREVIOUS))
  337.             return(TRUE);
  338.  
  339.         /* else just a normal file name was selected, so fall out to ... */
  340.         }
  341.     return(FALSE);
  342. }
  343.  
  344.  
  345.  
  346. VOID StuffFileName()
  347. /* If the selected name is a normal filename, stuffs the filename into the
  348.  * Name gadget.  If the selected name is a directory reference,
  349.  * adjusts the drawer gadget accordingly.
  350.  * Returns TRUE if the selected name was a directory-type reference
  351.  * (up or down), else returns FALSE for a normal filename.
  352.  */
  353. {
  354.     struct Remember *nextentry;
  355.     SHORT i;
  356.     UBYTE entryflags;
  357.  
  358.     if (OpenReqFileIO->NameCount)
  359.         {
  360.         /* Find the selected entry in the key list */
  361.         nextentry = OpenReqFileIO->NameKey;
  362.         for (i = OpenReqFileIO->CurrentPick; i; i--)
  363.             nextentry = nextentry->NextRemember;
  364.         i = StringLength(nextentry->Memory) + 1;
  365.         entryflags = *(nextentry->Memory + i);
  366.  
  367.         if (FlagIsSet(entryflags, NAMED_DIRECTORY))
  368.             {
  369.             /* If there's already a drawer reference, build a proper
  370.              * extension before adding the new to the end.
  371.              */
  372.             if (StringLength(OpenDrawerTextInfo.Buffer))
  373.                 ConcatString(OpenDrawerTextInfo.Buffer, "/");
  374.  
  375.              ConcatString(OpenDrawerTextInfo.Buffer,
  376.                     nextentry->Memory + DIR_TEXT_SIZE);
  377.  
  378.             ResetDrawerText(FALSE);
  379.             ResetNameText(TRUE);
  380.             }
  381.         else if (FlagIsSet(entryflags, NAMED_PREVIOUS))
  382.             {
  383.             /* Remove the last drawer reference */
  384.             StripLastDrawer();
  385.             ResetDrawerText(FALSE);
  386.             ResetNameText(TRUE);
  387.             }
  388.         else
  389.             {
  390.             /* Just a normal old file name was selected */
  391.              CopyString(OpenNameTextInfo.Buffer, nextentry->Memory);
  392.             ResetNameText(FALSE);
  393.             }
  394.         }
  395. }
  396.  
  397.  
  398.  
  399. /* ======================================================================= */
  400. /* === Proportional Gadget Routines ====================================== */
  401. /* ======================================================================= */
  402.  
  403. VOID SetOpenPropPot(resetpos)
  404. BOOL resetpos;
  405. /* This routine resets the vertical pot of the proportional gadget
  406.  * with respect to the current number of displayable file names.
  407.  */
  408. {
  409.     LONG slack, result;
  410.  
  411.     slack = OpenReqFileIO->NameCount - NAME_ENTRY_COUNT;
  412.  
  413.     if (slack > 0)
  414.         {
  415.         result = ((LONG)OpenReqFileIO->NameStart << 16) / slack;
  416.         if (result > 0xFFFF) result = 0xFFFF;
  417.         OpenPropInfo.VertPot = result;
  418.         }
  419.     else
  420.         OpenPropInfo.VertPot = 0;
  421.  
  422.     if (resetpos) OpenPropImage.TopEdge = 0;
  423. }
  424.  
  425.  
  426.  
  427. VOID InitOpenProp(resetpos)
  428. BOOL resetpos;
  429. /* This routine initializes the variable imagery of the proportional
  430.  * gadget and then initializes the gadget's vertical pot.
  431.  * The BOOL arg resetpos describes whether you want the call to 
  432.  * SetOpenPropPot() to reset the prop's knob position.
  433.  */
  434. {
  435.     LONG namecount, height;
  436.     SHORT i, i2;
  437.  
  438.     namecount = OpenReqFileIO->NameCount;
  439.  
  440.     if (namecount <= NAME_ENTRY_COUNT)
  441.         {
  442.         OpenPropInfo.VertBody = 0xFFFF;
  443.         ClearFlag(OpenPropInfo.Flags, FREEVERT);
  444.         height = OPENPROP_MAXHEIGHT;
  445.         }
  446.     else
  447.         {
  448.         OpenPropInfo.VertBody = ((LONG)NAME_ENTRY_COUNT << 16) / namecount;
  449.         SetFlag(OpenPropInfo.Flags, FREEVERT);
  450.         height = (OPENPROP_MAXHEIGHT * NAME_ENTRY_COUNT)  / namecount;
  451.         if (height < OPENPROP_MINHEIGHT) height = OPENPROP_MINHEIGHT;
  452.         }
  453.  
  454.     OpenPropImage.Height = height;
  455.     for (i = 0; i < OPENPROP_TOPHEIGHT; i++)
  456.         {
  457.         OpenPropData[i] = OpenPropTop[i];
  458.         OpenPropData[i + height] = OpenPropTop[i + OPENPROP_TOPHEIGHT];
  459.         }
  460.  
  461.     for (i = OPENPROP_TOPHEIGHT; i < height - OPENPROP_BOTTOMHEIGHT; i++)
  462.         {
  463.         OpenPropData[i] = OpenPropBottom[0];
  464.         OpenPropData[i + height] = OpenPropBottom[OPENPROP_BOTTOMHEIGHT];
  465.         }
  466.  
  467.     i2 = 0;
  468.     for (i = height - OPENPROP_BOTTOMHEIGHT; i < height; i++)
  469.         {
  470.         OpenPropData[i] = OpenPropBottom[i2];
  471.         OpenPropData[i + height] = OpenPropBottom[i2 + OPENPROP_BOTTOMHEIGHT];
  472.         i2++;
  473.         }
  474.  
  475.     SetOpenPropPot(resetpos);
  476. }
  477.  
  478.  
  479.  
  480.  
  481. /* ======================================================================= */
  482. /* === Requester Handler Routines ======================================== */
  483. /* ======================================================================= */
  484.  
  485. VOID StartOpenRequester()
  486. /* Called after the requester has been opened. */
  487. {
  488.     ActivateGadget(&OpenNameTextGadget, OpenReqWindow, OpenReq);
  489.  
  490.     if (FlagIsClear(OpenReqFileIO->Flags, GOOD_FILENAMES))
  491.         WarmStartFileIO(OpenReqFileIO);
  492.     else DrawSelectNames();
  493. }
  494.  
  495.  
  496.  
  497. SHORT HandleSelect(y, seconds, micros)
  498. SHORT y;
  499. LONG seconds, micros;
  500. /* This routine accepts that a GADGETDOWN occured at the given 
  501.  * pointer y offset.  This is translated into the ordinal number of the 
  502.  * filename selected by the user, and this is assigned to the 
  503.  * CurrentPick variable of the OpenReqFileIO structure.
  504.  * Returns:
  505.  *     1 = DirectoryName() returned TRUE (selection was directory name)
  506.  *     0 = new name selected, DirectoryName() returned FALSE (normal name)
  507.  *    -1 = same name selected, double-clicked
  508.  *    -2 = same name selected, not double-clicked
  509.  */
  510. {
  511.     SHORT returnvalue, oldy;
  512.     LONG oldseconds, oldmicros;
  513.  
  514.     y -= (OpenReq->TopEdge + OPENSELECT_TOP);
  515.     y = y / OPEN_LINEHEIGHT;
  516.     y += OpenReqFileIO->NameStart;
  517.     if (y >= OpenReqFileIO->NameCount)
  518.         y = OpenReqFileIO->NameCount - 1;
  519.  
  520.     oldseconds = OpenClickSeconds;
  521.     oldmicros = OpenClickMicros;
  522.     OpenClickSeconds = seconds;
  523.     OpenClickMicros = micros;
  524.  
  525.     oldy = OpenReqFileIO->CurrentPick;
  526.     OpenReqFileIO->CurrentPick = y;
  527.  
  528.     if (DirectoryName())
  529.         {
  530.         returnvalue = 1;
  531.         }
  532.     else
  533.         {
  534.         if (y == oldy)
  535.             {
  536.             /* User has selected the same name again.
  537.              * Was it done quickly enough to count as a
  538.              * double-click selection?
  539.              */
  540.             if (FlagIsClear(OpenReqFileIO->Flags, DOUBLECLICK_OFF)
  541.                     && DoubleClick(oldseconds, oldmicros,
  542.                             OpenClickSeconds, OpenClickMicros))
  543.                 returnvalue = -1;
  544.             else returnvalue = -2;
  545.             }
  546.         else
  547.             {
  548.             /* Do this work, what there is of it, only if the user 
  549.              * hasn't reselected an already-selected name.
  550.              */
  551.             returnvalue = 0;
  552.             }
  553.         }
  554.  
  555.     return(returnvalue);
  556. }
  557.  
  558.  
  559.  
  560. LONG HandleGadget(gadget, x, y, seconds, micros)
  561. struct Gadget *gadget;
  562. SHORT x, y;
  563. LONG seconds, micros;
  564. /* This routine handles one gadget selection */
  565. {
  566.     BOOL softbuild, hardbuild;
  567.     SHORT count;
  568.     LONG returnvalue;
  569.  
  570.     /* softbuild causes the file names to be refreshed.
  571.      * hardbuild causes the entire requester to be reestablished.
  572.      * either or both can be set.
  573.      */
  574.     softbuild = hardbuild = FALSE;
  575.  
  576.     /* count refers to the count that will be sent to StuffSelectNames().
  577.      * The default is 2, as you can see.
  578.      */
  579.    count = 2;
  580.  
  581.     /* If the selection of any gadget causes us to want the requester to
  582.      * go away, set the returnvalue non-zero.
  583.      */
  584.     returnvalue = 0;
  585.  
  586.     switch (gadget->GadgetID)
  587.         {
  588.         case OPENGADGET_SELECTNAME:
  589.             if (OpenReqFileIO->NameCount)
  590.                 {
  591.                 /* So our big name gadget was selected, eh?  Well, which one 
  592.                  * was the user really pointing at?
  593.                  */
  594.                 y = HandleSelect(y, seconds, micros);
  595.                 if (y < 0)
  596.                     {
  597.                     /* The user has reselected the old name */
  598.                     if (y == -1) returnvalue = -1;
  599.                     }
  600.                 else
  601.                     {
  602.                     /* The user has selected a new name */
  603.                     StuffFileName();
  604.                     softbuild = TRUE;
  605.                     if (y == 1) hardbuild = TRUE;
  606.                     count = 5;
  607.                     }
  608.                 }
  609.             break;
  610.         case OPENGADGET_UPGADGET:
  611.             if (OpenReqFileIO->NameStart)
  612.                 {
  613.                 OpenReqFileIO->NameStart--;
  614.                 softbuild = TRUE;
  615.                 }
  616.             break;
  617.         case OPENGADGET_DOWNGADGET:
  618.             if (OpenReqFileIO->NameStart + NAME_ENTRY_COUNT
  619.                     < OpenReqFileIO->NameCount)
  620.                 {
  621.                 OpenReqFileIO->NameStart++;
  622.                 softbuild = TRUE;
  623.                 }
  624.             break;
  625.         case OPENGADGET_PROPGADGET:
  626.             if (OpenReqFileIO->NameCount > NAME_ENTRY_COUNT)
  627.                 {
  628.                 SetNameStart();
  629.                 softbuild = TRUE;
  630.                 }
  631.             break;
  632.         case OPENGADGET_NEXTDISK:
  633.             /* Next disk!  Wholly mackerel!  First, if no "next" then split */
  634.             if (OpenReqFileIO->VolumeCount <= 1) break;
  635.  
  636.             OpenReqFileIO->VolumeIndex++;
  637.             if (OpenReqFileIO->VolumeIndex >= OpenReqFileIO->VolumeCount)
  638.                 OpenReqFileIO->VolumeIndex = 0;
  639.             CopyString(&OpenReqFileIO->DiskName[0], CurrentVolumeName());
  640.             ResetDiskText(FALSE);
  641.             ResetDrawerText(TRUE);
  642.  
  643.             /* Refresh the display so the user can see what's been done, as
  644.              * well as having the display refreshed all over again (hardbuild)
  645.              * below after the new filenames are retrieved.
  646.              */
  647.             softbuild = TRUE;
  648.             count = 5;
  649.  
  650.             /* Intentionally fall into DRAWER/DISKTEXT */
  651.  
  652.         case OPENGADGET_DRAWERTEXT:
  653.         case OPENGADGET_DISKTEXT:
  654.             ResetNameText(TRUE);
  655.             hardbuild = TRUE;
  656.             break;
  657.         default:
  658.             break;
  659.         }
  660.  
  661.     /* These are split intentionally, because setters of hardbuild might
  662.      * want a softbuild done first, to show why a hardbuild is being done!
  663.      */
  664.     if (hardbuild) SetWaitPointer(OpenReqWindow);
  665.     if (softbuild)
  666.         {
  667.         SetOpenPropPot();
  668.         StuffSelectNames(count);
  669.         }
  670.     if (hardbuild)
  671.         WarmStartFileIO(OpenReqFileIO);    /* Restart the lock etc. */
  672.  
  673.     return(returnvalue);
  674. }
  675.  
  676.  
  677.  
  678. VOID DiskInserted()
  679. /* This routine is called by the RequesterSupport code whenever a new disk
  680.  * has been inserted.  This allows the user to swap disks while the
  681.  * requester is displayed.  Unfortunately, I have no way of knowing which
  682.  * disk swapped, so I have to restart the requester more or less.
  683.  * Not too bad, but a little unpleasant.
  684.  */
  685. {
  686.     SetWaitPointer(OpenReqWindow);
  687.     SetFlag(OpenReqFileIO->Flags, DISK_HAS_CHANGED);
  688.     BuildVolumeTable(OpenReqFileIO);
  689.     CopyString(&OpenReqFileIO->DiskName[0], CurrentVolumeName());
  690.     WarmStartFileIO(OpenReqFileIO);
  691. }
  692.  
  693.  
  694.  
  695. VOID PropMouseMoves()
  696. /* This routine is called by RequesterSupport whenever the mouse moves
  697.  * while a FOLLOWMOUSE gadget is set.  The only FOLLOWMOUSE gadget is
  698.  * the prop gadget, so...
  699.  */
  700. {
  701.     /* ... if there's more names than the number of visible names,
  702.      * then reset the name start and redisplay the names.
  703.      */
  704.     if (OpenReqFileIO->NameCount > NAME_ENTRY_COUNT)
  705.         {
  706.         SetNameStart();
  707.         StuffSelectNames(2);
  708.         }
  709. }
  710.  
  711.